import axios from 'axios'
import qs from 'qs'
import constant from '@/config/constant.js'
import mapUtil from '@/utils/mapUtil.js'
import store from '@/store/index.js'
const mapExtend = {
  AK: "OTIwMzdiNmQzOWQ4NGIwMWI1ZWNjYTU2ODE0NzczZDg",
  init() {
    this.extend();
  },
  extend() {
    this.extendMap();
    this.extendLayer();
    this.extendDrawLayer();
    this.extendGraphicLayer();
    this.extendTileLayer();
    this.extendLegend();
  },
  extendMap() {
    let prototype = G.Map.prototype;
    prototype.getZoom = function () {
      let zoomReses = this.options.zoomReses;
      let curRes = this.getResolution();
      for (let i = 0, len = zoomReses.length; i < len - 1; i++) {
        if (zoomReses[i] >= curRes && curRes >= zoomReses[i + 1]) {
          if (Math.abs(zoomReses[i] - curRes) > Math.abs(zoomReses[i + 1] - curRes)) {
            return i + 1;
          } else if (Math.abs(zoomReses[i] - curRes) < Math.abs(zoomReses[i + 1] - curRes)) {
            return i;
          }
        }
      }
    };
    prototype.centerAndZoom = function (mapPoint, zoom) {
      this.zoomRes(mapPoint, this.options.zoomReses[zoom]);
    };
    prototype.setBasemap = function (basemapType) {
      let basemap = constant.BASE_MAP_LIST[basemapType];
      let basemapLayer = this.getLayerByName('basemap');
      if (!basemapLayer) {
        basemapLayer = new G.Layer.Tile(basemap.url, {
          cluster: basemap.cluster,
        });
        basemapLayer.options.name = 'basemap';
        this.addLayer(basemapLayer);
      }
      if (basemap.cluster) {
        basemapLayer.options.cluster = basemap.cluster;
      }
      basemapLayer.options.basemapType = basemapType;
      basemapLayer.setUrl(basemap.url);
      return basemapLayer;
    };
    prototype.getLayerByName = function (name) {
      let layers = this.getLayers();
      for (let i in layers) {
        let layer = layers[i];
        let layerName = layer.options.name || layer.name;
        if (layerName == name) {
          return layer;
        }
      }
      return null;
    };
    prototype.copyMap = function (sourceMap) {
      let layers = sourceMap.getLayers();
      for (let i in layers) {
        let layer = layers[i];
        //console.log(layer.options.name);
        if (layer instanceof G.Layer.Draw) {
          // let targetLayer = new G.Layer.Draw(); 
          // targetLayer.copyLayer(layer);
          // targetLayer.options.name = layer.options.name;
          // if(!layer.isVisible()){
          //     targetLayer.hide();
          // }
          // this.addLayer(targetLayer);
          // targetLayer.bringToOrder(layer.getOrder());
          continue;
        } else if (layer instanceof G.Layer.Graphic) {
          let targetLayer = new G.Layer.Graphic();
          targetLayer.copyLayer(layer);
          targetLayer.options.name = layer.options.name;
          if (!layer.isVisible()) {
            targetLayer.hide();
          }
          this.addLayer(targetLayer);
          targetLayer.bringToOrder(layer.getOrder());
          //console.log(targetLayer);

        } else if (layer instanceof G.Layer.Tile) {
          if (layer.options.name == 'basemap') {
            this.setBasemap(layer.options.basemapType).bringToOrder(layer.getOrder());

          } else {
            let targetLayer = new G.Layer.Tile(layer.url, {
              cluster: ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8'],
              crossOrigin: "",
              tileEnlarge: false,
              //minRes:layer.options.minRes,
              //maxRes:layer.options.maxRes,
            });
            if (layer.options.name == 'district') {
              targetLayer.options.lastCodes = layer.options.lastCodes;
            }
            targetLayer.options.name = layer.options.name;
            targetLayer.options.dataUid = layer.options.dataUid;
            targetLayer.options.configJson = layer.options.configJson;
            // let arr=['province', 'city', 'district'];
            // if(!layer.isVisible()&&!arr.includes(targetLayer.options.name)){
            //     targetLayer.hide();    
            // }
            if (!layer.isVisible()) {
              targetLayer.hide();
            }
            this.addLayer(targetLayer);
            targetLayer.bringToOrder(layer.getOrder());

          }
        }
      }
    };
    prototype.removeLayers = function (...params) {
      let layers = this.getLayers();
      for (let i in layers) {
        let layer = layers[i];
        layer.remove();
        layer.eventFnList && layer.removeEvent();
        delete layers[i];
      }
      return this;
    };
    prototype.clearMap = function (params) {
      this.hidePopup(true);
      let widgets = this.options.widgets;
      for (let i in widgets) {
        widgets[i] = false;
      }
      document.querySelector('.g-container').style.cursor = "";

      store.state.multilayerData = [];
      if (store.state.curNav.firstMenu && store.state.curNav.firstMenu.text != '模型') {
        store.state.fullPanel.visible = false;
      }
      let layers = this.getLayers();
      for (let i in layers) {
        let layer = layers[i];
        if (layer.options.hasFlag && params.hasFlag) {
          continue;
        }
        if (params && params.excludes && params.excludes.includes(layer.options.name)) {
          continue;
        }
        if (layer.options.category && layer.options.category == 'layer-list') {
          continue;
        }
        if (layer.options.category) {
          if (layer.options.category == 'layer-list') {
            continue;
          }
          if (layer.options.category == 'measure') {
            layer.clear();
            layer.endDraw();
            continue;
          }
        }

        if (layer instanceof G.Layer.Graphic) {
          let graphics = layer.all();
          graphics.forEach((item, index) => {
            if (item.options.name == 'animLine') {
              item.stop();
            }
          });
          layer.clear();
          layer.remove();
          layer.hideLegend();
          // layer.setLegend({
          //     title: '',
          //     type: '',
          //     data: []
          // });
          // layer.hideLegend();
        }
        if (layer instanceof G.Layer.Draw) {
          layer.endDraw();
          layer.remove();
          layer.hideLegend();
          // layer.setLegend({
          //     title: '',
          //     type: '',
          //     data: []
          // });
          // layer.hideLegend();
        }
        if (layer instanceof G.Layer.TiledHeat) {
          layer.remove();
          layer.eventFnList && layer.removeEvent();
        }
        if (layer instanceof G.Layer.Tile) {
          layer.remove();
          layer.eventFnList && layer.removeEvent();
        }
      }
    };
    prototype.changeLayerOpacity = function (value) {
      let layers = this.getLayers();
      let layer;
      for (let i in layers) {
        layer = layers[i];
        if (layer instanceof G.Layer.Draw || layer instanceof G.Layer.Graphic) {
          let graphics = layer.all();
          graphics.forEach((graphic, index) => {
            if (graphic.options.hasOwnProperty('lineOpacity')) {
              graphic.options.lineOpacity = value;
            }
            if (graphic.options.hasOwnProperty('outlineOpacity')) {
              graphic.options.outlineOpacity = value;
            }
            if (graphic.options.hasOwnProperty('fillOpacity')) {
              graphic.options.fillOpacity = value;
            }
          });
        } else if (layer.options.name != 'basemap') {
          layer.options.opacity = value;
        }
      }
      this.redraw();
    };
  },
  extendLayer() {
    let self = this;
    let prototype = G.Layer.prototype;
    prototype.setLayerLegend = function (title, buckets) {
      buckets = buckets ? buckets : [];
      let vizConfig;
      if (this.options.configJson && this instanceof G.Layer.Tile) {
        vizConfig = this.options.configJson.vizConfig;
        if (!buckets || buckets.length <= 0) {
          buckets = vizConfig.buckets;
        }
        if (vizConfig && vizConfig.type == 'polygon-simple') {
          return;
        }
      }
      let legend = document.querySelector('.g-legend');
      if (!buckets || buckets.length <= 0) {
        legend.style.display = "none";
        return;
      }
      let value = '';
      let legendData = [];
      let bucketType = Number.isNaN(parseFloat(buckets[0].value)) ? 'category' : 'choropleth';
      for (let i = 0, len = buckets.length; i < len; i++) {
        let bucket = buckets[i];
        if (bucketType == 'category') {
          value = bucket.value
        } else if (bucketType == 'choropleth') {
          if (i === len - 1) {
            value = bucket.value === 0 ? 0 : `0 ~ ${bucket.value}`;
          } else {
            value = `${buckets[i+1].value} ~ ${bucket.value}`;
          }
        }
        legendData.push({
          color: bucket.color,
          value: value
        });
      }
      legend.style.display = "block";
      title = title ? title : this.options.configJson.text;
      let legendType = 'polygon';
      if (vizConfig && vizConfig.type.includes('marker')) {
        legendType = 'marker';
      } else if (vizConfig && vizConfig.type.includes('polyline')) {
        legendType = 'polyline';
      }
      if (vizConfig && vizConfig.type == 'marker-bubble') {
        let interval = Math.round(40 / legendData.length - 1)
        legendData.forEach((item, index) => {
          item.size = 40 - index * interval;
          item.color = vizConfig.markerColor;
        });
      }
      //console.log(legendData);

      this.setLegend({
        title: title,
        type: legendType,
        data: legendData
      });
      //this._map.options.legend.open();

    };
  },
  extendDrawLayer() {
    let self = this;
    // let prototype = G.Layer.Draw.prototype;
    // prototype.copyLayer = function(sourceLayer){
    //     let graphics = sourceLayer.all();
    //     graphics.forEach((graphic)=>{
    //         this.add(graphic.clone());
    //     });
    //     return this;
    // };
  },
  extendGraphicLayer() {
    let self = this;
    let prototype = G.Layer.Graphic.prototype;
    prototype.copyLayer = function (sourceLayer) {
      let graphics = sourceLayer.all();
      graphics.forEach((graphic) => {
        this.add(graphic.clone());

      });
      if (!sourceLayer.isVisible()) {
        this.hide();
      }
    };
    prototype.remove = function (type) {
      if (type) {
        let graphics = this.all();
        graphics.forEach((graphic, index) => {
          if (graphic.options.type == type) {
            graphic.remove();
          }
        });
      } else {
        this.clear();
      }
      return this;
    };
    prototype.filter = function (type) {
      let result = [];
      if (type) {
        let graphics = this.all();
        result = graphics.filter((graphic, index) => {
          return graphic.options.type == type
        });
      }
      return result;
    };
  },
  extendTileLayer() {
    let self = this;
    let prototype = G.Layer.Tile.prototype;
    let url = `http://geohey.com/s/dataviz/config?ak=${self.AK}`;

    prototype.setLayerViz = function (configJson, filter, succFn) {
      configJson = configJson ? configJson : this.options.configJson;
      if (!configJson) {
        return;
      }
      filter = filter ? filter : "";
      configJson.filter = filter;
      this.options.dataUid = configJson.dataUid;
      this.options.configJson = configJson;
      let params = {
        configJson: JSON.stringify(configJson)
      };
      axios.post(url, qs.stringify(params))
        .then((data) => {
          let vizId = data.data.data.vizId;
          let vizUrl = `http://{s}.geohey.com/s/dataviz/${vizId}/{z}/{x}/{y}.png?retina={i}&ak=${self.AK}`;
          this.setUrl(vizUrl);
          succFn && succFn();
        }).catch(function (error) {
          console.log(error);
        });
      return this;
    };
    prototype.setLayerRes = function () {

    };
    prototype.addEvent = function (type, fn) {
      if (!this.eventFnList) {
        this.eventFnList = [];
      }
      let eventFnItem = {
        type: type,
        eventFn: null,
      };
      this.eventFnList.push(eventFnItem);
      eventFnItem.eventFn = async (e) => {
        if (type == 'click') {
          this.handleClickFn(e, fn);
        } else if (type == 'zoomEnd') {
          this.handleZoomEndFn(e, fn);
        }
      };
      this._map.bind(type, eventFnItem.eventFn);
    };
    prototype.handleClickFn = function (e, fn) {
      if (mapUtil.isBusy()) {
        return;
      }
      let layers = e.target._layers;
      let event = {
        mapX: e.mapX,
        mapY: e.mapY,
        screenX: e.screenX,
        screenY: e.screenY
      };
      for (let i in layers) {
        if (layers[i].options.name == this.options.name && this.isVisible() && layers[i] instanceof G.Layer.Tile) {
          fn && fn(event);
          break;
        }
      }
    };
    prototype.handleZoomEndFn = function (e, fn) {
      //console.log(e);
      e.targetLayer = this;
      fn && fn(e);
    };
    prototype.removeEvent = function (type) {
      if (this.eventFnList) {
        this.eventFnList.forEach((item, index) => {
          if (type) {
            if (type == item.type) {
              this._map.unbind(item.type, item.eventFn);
            }
          } else {
            this._map.unbind(item.type, item.eventFn);
          }
        });
      }
      this.eventFnList = null;
    };
    prototype.queryTask = function (params, succFn, errorFn) {
      let url = `http://geohey.com/s/data/${this.options.dataUid}/query?ak=${self.AK}`;
      axios.post(url, qs.stringify(params))
        .then((data) => {
          succFn && succFn(data);
        }).catch((error) => {
          errorFn && errorFn(error);
          console.log(error);
        });
    };
    prototype.identifyTask = function (params, succFn, errorFn) {
      let url = `http://geohey.com/s/dataviz/identify?ak=${self.AK}`;
      axios.post(url, qs.stringify(params))
        .then((data) => {
          console.log(data);
          succFn && succFn(data);
        }).catch(function (error) {
          errorFn && errorFn(error);
          console.log(error);
        });
    };
  },
  extendLegend() {
    let prototype = G.Legend.prototype;
    prototype.hide = function () {
      let legend = document.querySelector('.g-legend');
      legend.style.display = "none";
    };
    prototype.show = function () {
      let legend = document.querySelector('.g-legend');
      legend.style.display = "block";
    };
  }
};
mapExtend.init();

export default mapExtend;
